package com.mall.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mall.db.api.*;
import com.mall.exception.ConsumerException;
import com.mall.pageResult.PageResult;
import com.mall.pojo.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class RoleService {

    @DubboReference
    private UmsRoleApi roleApi;

    @DubboReference
    private UmsRoleMenuRelationApi roleMenuRelationApi;

    @DubboReference
    private UmsMenuApi menuApi;

    @DubboReference
    private UmsRoleResourceRelationApi roleResourceRelationApi;

    @DubboReference
    private UmsResourceApi resourceApi;

    /**
     * 获取所有角色
     *
     * @return
     */
    public List<UmsRole> listAll() {
        return roleApi.findAll();
    }

    /**
     * 根据角色名称分页获取角色列表
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public PageResult<UmsRole> list(Integer pageNum, Integer pageSize, String keyword) {
        Page<UmsRole> page = roleApi.list(pageNum, pageSize, keyword);
        PageResult<UmsRole> result = new PageResult<>();
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setList(page.getRecords());
        result.setTotalPage(Convert.toInt(page.getPages()));
        result.setTotal(Convert.toInt(page.getTotal()));
        return result;
    }

    /**
     * 添加角色
     *
     * @param role
     * @return
     */
    public Integer create(UmsRole role) {
        UmsRole umsRole = roleApi.findByName(role.getName());
        if (ObjectUtil.isNotNull(umsRole)) {
            throw new ConsumerException("该角色已存在");
        }
        role.setCreateTime(new Date(System.currentTimeMillis()));
        role.setSort(0);
        Integer count = roleApi.addRole(role);
        return count;
    }

    /**
     * 修改角色
     *
     * @param id
     * @param role
     * @return
     */
    public Integer update(Integer id, UmsRole role) {
        UmsRole umsRole = roleApi.findByName(role.getName());
        if (ObjectUtil.isNotNull(umsRole)) {
            throw new ConsumerException("该角色已存在");
        }
        return roleApi.update(role);
    }

    /**
     * 删除角色
     *
     * @param ids
     * @return
     */
    public Integer delete(Integer ids) {
        UmsRole role = roleApi.findById(ids);
        if (role.getStatus() == 1) {
            throw new ConsumerException("不可删除已启用的角色");
        }
        Integer count = roleApi.delete(ids);
        return count;
    }

    /**
     * 修改角色状态
     *
     * @param id
     * @param status
     * @return
     */
    public Integer updateStatus(Integer id, Integer status) {
        UmsRole role = roleApi.findById(id);
        role.setStatus(status);
        return roleApi.update(role);
    }

    /**
     * 获取角色相关菜单
     *
     * @param roleId
     * @return
     */
    public List<UmsMenu> listMenu(Integer roleId) {
        List<UmsMenu> menuList = new ArrayList<>();
        List<UmsRoleMenuRelation> relationList = roleMenuRelationApi.findByRole(Convert.toLong(roleId));
        if (relationList.size() == 0) {
            return menuList;
        }
        List<Long> menuIds = CollUtil.getFieldValues(relationList, "menuId", Long.class);
        menuList = menuApi.findByIds(menuIds);
        return menuList;
    }

    /**
     * 给角色分配菜单
     * @param roleId
     * @param menuIds
     * @return
     */
    public Integer allocMenu(Integer roleId, Integer[] menuIds) {
        Integer count = 0;
        roleMenuRelationApi.delete(roleId);
        for (Integer menuId : menuIds) {
            UmsRoleMenuRelation relation = new UmsRoleMenuRelation();
            relation.setRoleId(Convert.toLong(roleId));
            relation.setMenuId(Convert.toLong(menuId));
            roleMenuRelationApi.add(relation);
            count++;
        }
        return count;
    }

    /**
     * 获取角色相关资源
     * @param roleId
     * @return
     */
    public List<UmsResource> listResource(Integer roleId) {
        List<UmsResource> resourceList = new ArrayList<>();
        List<UmsRoleResourceRelation> relationList = roleResourceRelationApi.findByRole(Convert.toLong(roleId));
        if (relationList.size() == 0) {
            return resourceList;
        }
        List<Long> resourceIds = CollUtil.getFieldValues(relationList, "resourceId", Long.class);
        resourceList = resourceApi.findByIds(resourceIds);
        return resourceList;
    }

    /**
     * 给角色分配资源
     * @param roleId
     * @param resourceIds
     * @return
     */
    public Integer allocResource(Integer roleId, Integer[] resourceIds) {
        Integer count = 0;
        roleResourceRelationApi.delete(roleId);
        for (Integer resourceId : resourceIds) {
            UmsRoleResourceRelation relation = new UmsRoleResourceRelation();
            relation.setRoleId(Convert.toLong(roleId));
            relation.setResourceId(Convert.toLong(resourceId));
            roleResourceRelationApi.add(relation);
            count++;
        }
        return count;
    }
}
